package jcolibri.test.recomendador.datos;

import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;

import jcolibri.cbrcore.CBRCase;
import jcolibri.cbrcore.CaseComponent;
import jcolibri.connector.ExtendedDataBaseConnector;

public class ExtendedExtendedDatabaseConnector extends ExtendedDataBaseConnector{

    /**
     * Executes the given SQL statement, which returns a single ResultSet object
     * @param sqlString contains the sql statement to execute.
     * @return a ResultSet object or null if there was any error.
     */
    public ResultSet executeSQLQuery(String sqlString)
    {
	try
	{
	    Session session = sessionFactory.openSession();
	    Statement ps = session.connection().createStatement();
	    org.apache.commons.logging.LogFactory.getLog(this.getClass()).info("Executing SQL-Query statement: "+sqlString);
	    ResultSet rs = ps.executeQuery(sqlString);
	    session.close();
	    return rs;
	} catch (Exception e)
	{
	    org.apache.commons.logging.LogFactory.getLog(this.getClass()).error(e);
	}
	return null;
    }    


	
	
	
	
	
	
	/* (non-Javadoc)
	 * @see jcolibri.cbrcore.Connector#retrieveAllCases()
	 */
	public Collection<CBRCase> retrieveAllCases(){
		
		java.util.ArrayList<CBRCase> res = new java.util.ArrayList<CBRCase>();
	
		try 
		{
			Session session;// = sessionFactory.openSession();				
			Transaction transaction; //= session.beginTransaction();
					
			// Declaramos tres listas para la descripci�n, soluci�n y resultado de cada caso. Aprovecharemos el hecho de que al recuperarse 
 			// de la misma tabla, est�n en el mismo orden. Es decir en la posicion 1 de cada lista est� la descripci�n, soluci�n y resultado
			// del caso 1. En la posici�n n de cada lista esta la descripci�n, soluci�n y resultado del caso n.
 			List descList = null;
			List solList = null;
			List resList=null;
		
			HashMap<Object, CaseComponent> justSolList = null;
			
			
			
			if(solutionClassName != null)
			{
				session = sessionFactory.openSession();	
				transaction = session.beginTransaction();

				solList = session.createQuery("from " + solutionClassName).list();
				
				transaction.commit();
				session.close();
				
//				for(Iterator iter = l.iterator(); iter.hasNext();)
//				{
//					CaseComponent cc = (CaseComponent)iter.next();
//					solList.put(cc.getIdAttribute().getValue(cc), cc);
//				}
			}
			if(justOfSolutionClassName != null)
			{
				session = sessionFactory.openSession();	
				transaction = session.beginTransaction();

				justSolList = new HashMap<Object, CaseComponent>();
				List l = session.createQuery("from " + justOfSolutionClassName).list();
				transaction.commit();
				session.close();

				for(Iterator iter = l.iterator(); iter.hasNext();)
				{
					CaseComponent cc = (CaseComponent)iter.next();
					justSolList.put(cc.getIdAttribute().getValue(cc), cc);
				}
			}
			if(resultClassName != null)
			{
				session = sessionFactory.openSession();	
				transaction = session.beginTransaction();

//				resList = new HashMap<Object, CaseComponent>();
				resList = session.createQuery("from " + resultClassName).list();
				transaction.commit();
				session.close();

//				for(Iterator iter = l.iterator(); iter.hasNext();)
//				{
//					CaseComponent cc = (CaseComponent)iter.next();
//					resList.put(cc.getIdAttribute().getValue(cc), cc);
//				}
			}

			session = sessionFactory.openSession();	
			transaction = session.beginTransaction();
			descList = session.createQuery("from "+ descriptionClassName).list();			
			transaction.commit();
			session.close();

			Iterator iterSol = solList.iterator();
			Iterator iterRes = resList.iterator();
		
//Rellenamos las partes de descripci�n, soluci�n y resultado de cada caso
//en cada vuelta del bucle. Podemos hacer esto porque tal como hemos comentado
//anteriormente en el c�digo las listas de descripciones, soluciones y resultados
//est�n en el mismo orden.
			for(Iterator iter = descList.iterator(); iter.hasNext();)
			{
        		CBRCase _case = new CBRCase();
				CaseComponent desc = (CaseComponent)iter.next();
				CaseComponent sol  = (CaseComponent)iterSol.next(); 
				CaseComponent result  = (CaseComponent)iterRes.next();
				_case.setDescription(desc);
				
				if(solutionClassName != null)
				{
					_case.setSolution(sol);
				}
				if(justOfSolutionClassName != null)
				{
					CaseComponent cc = justSolList.get(desc.getIdAttribute().getValue(desc));
					if(cc != null)
						_case.setJustificationOfSolution(cc);
				}						
				if(resultClassName != null)
				{
				   _case.setResult(result);
				}
				res.add(_case);
			}
			
			//transaction.commit();
			//session.close();
			
		} catch (Exception e) {
			org.apache.commons.logging.LogFactory.getLog(this.getClass()).error(e);
		}
		org.apache.commons.logging.LogFactory.getLog(this.getClass()).info(res.size()+" cases read from the database.");
		return res;
	}

}
